﻿using System.Windows;
using mitasoft.Books.Core;
using System.Collections.Generic;
using mitasoft.Books.DataLayer;
using System.Linq;
using System;
using mitasoft.Books.Client.Desktop.Services;
using System.Windows.Threading;
using mitasoft.Books.Client.Desktop.Core;
using mitasoft.Books.Client.Desktop.Helpers;
using System.IO;
using mitasoft.Books.Client.Desktop.Properties;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Reflection;


namespace mitasoft.Books.Client.Desktop
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region private fields

        private Services.BooksDiscoveryService discoveryService = null;
        private Services.ApplicationMessagesService appMessagesService = null;
        private Services.StoreService storeService = null;

        private Dispatcher uiDispatcher;
        private List<FileDescriptor> booksResult = null;

        #endregion

        #region ctor

        public MainWindow()
        {
            InitializeComponent();

            //init 
            ServiceManager.AddService(new Services.BooksDiscoveryService());
            ServiceManager.AddService(new Services.ApplicationMessagesService());
            ServiceManager.AddService(new Services.StoreService());

            TaskHelper.Init(this.Dispatcher, this.progressBar);
            uiDispatcher = this.Dispatcher;

            //get discovery service
            discoveryService = ServiceManager.GetService<Services.BooksDiscoveryService>();
            appMessagesService = ServiceManager.GetService<Services.ApplicationMessagesService>();
            storeService = ServiceManager.GetService<Services.StoreService>();

            //hook event
            appMessagesService.OnMessageAdded += new mitasoft.Books.Client.Desktop.Services.ApplicationMessagesService.ApplicationMessagesEventHandler(appMessagesService_OnMessageAdded);
        }

        #endregion

        #region event handlers

        private void appMessagesService_OnMessageAdded(object sender, ApplicationMessageEventArgs e)
        {
            uiDispatcher.BeginInvoke(
                (Action)delegate()
                {
                    lstMessages.ItemsSource = e.Messages;
                });
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //Get defined categories
            var listCategory = new CategoryFinder().GetCategoryList();
            listCategory.Sort();

            List<string> listCategoryForCombo = new CategoryFinder().GetCategoryList();
            listCategoryForCombo.Add("");
            listCategoryForCombo.Sort();

            //Bind list to controls
            this.cbSearchCategory.ItemsSource = listCategoryForCombo;
            this.Resources["CategoryList"] = listCategory;

            //version display
            versionStatus.Content = string.Format("{0}.{1}.{2}",
                 Assembly.GetEntryAssembly().GetName().Version.Major,
                 Assembly.GetEntryAssembly().GetName().Version.Minor,
                 Assembly.GetEntryAssembly().GetName().Version.Build);
        }

        private void btnLoadDirectory_Click(object sender, RoutedEventArgs e)
        {
            string path = DialogsHelper.ShowBrowseFolder();

            if (!string.IsNullOrEmpty(path))
            {
                //TaskHelper.RunSynced(
                //    () => { },
                //    () =>
                //    {
                appMessagesService.ClearMessagesStack();
                statusMessage.Content = "";

                lstMessages.ItemsSource = null;
                gridBooks.ItemsSource = null;

                appMessagesService.AddMessage("Search started", ApplicationMessageEnum.info);
                //});

                //search for files

                TaskHelper.RunSynced(
                    () =>
                    {
                        booksResult = discoveryService.SearchFolder(path);
                    },
                    () =>
                    {
                        gridBooks.ItemsSource = booksResult;
                        appMessagesService.AddMessage("Search ended", ApplicationMessageEnum.info);
                    });
            }
        }
        private void btnProcess_Click(object sender, RoutedEventArgs e)
        {
            Core.CategoryFinder finder = new CategoryFinder();

            foreach (var book in booksResult)
            {
                book.Category = finder.GetCategory(book.FileName);
            }

            //gridBooks.SelectedValue

            gridBooks.ItemsSource = null;
            gridBooks.ItemsSource = booksResult;
            statusMessage.Content = "Processing complete";
        }
        private void btnPack_Click(object sender, RoutedEventArgs e)
        {
            appMessagesService.AddMessage("Pack started", ApplicationMessageEnum.info);

            TaskHelper.RunSynced(
                () =>
                {
                    EnsureCategoryFolders();
                },
                () =>
                {
                    statusMessage.Content = "Packed completed";
                    appMessagesService.AddMessage("Pack ended", ApplicationMessageEnum.info);
                });
        }

        private void menuCategories_Click(object sender, RoutedEventArgs e)
        {

        }

        private void tbSearchNume_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            DoSearch();
        }
        private void cbSearchCategory_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            DoSearch();
        }

        #endregion

        #region private methods

        private void EnsureCategoryFolders()
        {

            List<FileDescriptor> storedItems = null;
            if (!Directory.Exists(Settings.Default.StoreDirectory))
            {
                Directory.CreateDirectory(Settings.Default.StoreDirectory);
            }
            else
            {
                storedItems = discoveryService.SearchFolder(Settings.Default.StoreDirectory);
            }

            if (booksResult != null)
            {
                var categories = (from b in booksResult
                                  where b.Category != null && !b.Category.StartsWith("-")
                                  select b.Category).Distinct();

                foreach (var category in categories)
                {
                    //prepare folder
                    string bookStoreFolder = CategoryPath(category);

                    if (!Directory.Exists(bookStoreFolder))
                        Directory.CreateDirectory(bookStoreFolder);

                    //move book
                    var booksPerCategory = from b in booksResult
                                           where b.Category == category
                                           select b;

                    List<string> queryAvailbleBooks = null;
                    if (storedItems != null)
                    {
                        queryAvailbleBooks = (from ab in storedItems
                                              select ab.FileHash).ToList();
                    }

                    string movingPath = "";
                    foreach (var b in booksPerCategory)
                    {
                        movingPath = b.FilePath;

                        try
                        {
                            if (storedItems != null && queryAvailbleBooks != null && queryAvailbleBooks.Contains(b.FileHash))
                            {
                                appMessagesService.AddMessage(string.Format("Book {0} is already in store !", b.FileName), ApplicationMessageEnum.error);
                            }
                            else
                            {
                                File.Copy(b.FilePath, Path.Combine(bookStoreFolder, b.FileName));
                                appMessagesService.AddMessage(string.Format("I copied {0} !", b.FileName), ApplicationMessageEnum.info);
                            }
                        }
                        catch (Exception ex)
                        {
                            appMessagesService.AddMessage(string.Format("I can't move {0} - {1}", movingPath, ex.Message), ApplicationMessageEnum.error);
                        }
                    }
                }
            }

        }

        private void DoSearch()
        {
            statusMessage.Content = "";
            List<FileDescriptor> searchResults = null;
            string nameSearchParam = tbSearchNume.Text.ToLower();
            string categorySearchParam = cbSearchCategory.SelectedValue.ToString().ToLower();

            if (booksResult != null)
            {
                TaskHelper.RunSynced(
                    () =>
                    {
                        searchResults = booksResult.Where(f =>

                            !string.IsNullOrEmpty(f.FileName) &&
                            !string.IsNullOrEmpty(f.Category) &&

                            f.FileName.ToLower().Contains(nameSearchParam) &&
                            f.Category.ToLower().Contains(categorySearchParam)

                            ).ToList();
                    },
                    () =>
                    {
                        gridBooks.ItemsSource = searchResults;
                        statusMessage.Content = "finished";
                    });
            }
        }

        private string CategoryPath(string category)
        {
            return Path.Combine(Settings.Default.StoreDirectory, category);
        }

        #endregion

        private void btnOpenFile_Click(object sender, RoutedEventArgs e)
        {
            if (gridBooks.SelectedItem != null)
            {
                var pathToExecute = ((mitasoft.Books.Core.FileDescriptor)(gridBooks.SelectedItem)).FilePath;
                Process.Start(pathToExecute);
            }
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            App.Current.Shutdown();
        }



    }
}
